﻿using System;
using KC.Framework.Util;
using StackExchange.Redis;

namespace KC.Storage.Util.Cache
{
    public static class RedisConnectionHelper
    {
        private static readonly Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(KC.Framework.Base.GlobalConfig.RedisConnectionString);
            connectionMultiplexer.PreserveAsyncOrder = false;

            //注册如下事件
            connectionMultiplexer.ConnectionFailed += MuxerConnectionFailed;
            connectionMultiplexer.ConnectionRestored += MuxerConnectionRestored;
            connectionMultiplexer.ErrorMessage += MuxerErrorMessage;
            connectionMultiplexer.ConfigurationChanged += MuxerConfigurationChanged;
            connectionMultiplexer.HashSlotMoved += MuxerHashSlotMoved;
            connectionMultiplexer.InternalError += MuxerInternalError;
            return connectionMultiplexer;
        });

        static RedisConnectionHelper()
        {
        }

        //public static ConnectionMultiplexer Manager
        //{
        //    get
        //    {
        //        return lazyConnection.Value;
        //    }
        //}

        private static readonly object Locker = new object();
        private static ConnectionMultiplexer _instance;
        /// <summary>
        /// 单例获取
        /// </summary>
        public static ConnectionMultiplexer Manager
        {
            get
            {
                if (_instance == null)
                {
                    lock (Locker)
                    {
                        if (_instance == null || !_instance.IsConnected)
                        {
                            _instance = lazyConnection.Value;
                        }
                    }
                }
                return _instance;
            }
        }

        #region 事件

        /// <summary>
        /// 配置更改时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
        {
            LogUtil.LogInfo("Configuration changed: " + e.EndPoint);
        }

        /// <summary>
        /// 发生错误时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
        {
            LogUtil.LogError("ErrorMessage: " + e.Message);
        }

        /// <summary>
        /// 重新建立连接之前的错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
        {
            LogUtil.LogInfo("ConnectionRestored: " + e.EndPoint);
        }

        /// <summary>
        /// 连接失败 ， 如果重新连接成功你将不会收到这个通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            LogUtil.LogError("重新连接：Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));
        }

        /// <summary>
        /// 更改集群
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
        {
            LogUtil.LogInfo("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
        }

        /// <summary>
        /// redis类库错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
        {
            LogUtil.LogError("InternalError:Message" + e.Exception.Message);
        }

        #endregion 事件
    }
}
